﻿/**
* Copyright © 2015 CD Projekt Red. All Rights Reserved.
*/

using System;
using System.IO;
using System.Threading.Tasks;
namespace Red.CommUtils
{
    public delegate void ChannelIncomingMessageEventHandler(comm.Message message, IResponse responseGateway);
    public delegate void MessageResponseHandler(comm.Message response);
    public delegate void DisconnectedHandler();

    public interface IChannel
    {
        string Name { get; }
        ulong TotalBytesReceived { get; }
        ulong TotalBytesSent { get; }

        bool IsOpen();
        void ShutDown();
        void Send( comm.Message message );
        void SendAck(comm.Message message, MessageResponseHandler handler);
        comm.Message SendAndWait(comm.Message message, int timeoutInMS);
        void RegisterListener(ChannelIncomingMessageEventHandler listener);
        void UnregisterListener(ChannelIncomingMessageEventHandler listener);
        Task<bool> TryReconnect( int timeout );

        event DisconnectedHandler Disconnected;
    }

    [Flags]
    public enum MessageFlags
    {
        FireAndForget = 0x1,
        NeedsAck = 0x2,
        Ack = 0x4,
        ReroutedResponse = 0x8,
    }

    public interface IResponseFactory
    {
        IResponse Create( MessageFlags flags = MessageFlags.FireAndForget, ushort handle = 0 );
    }

    public delegate bool OnPacketEventHandler( Stream packet, IResponseFactory responseFactory );
    public interface IChannelConnection
    {
        ulong TotalBytesReceived { get; }
        ulong TotalBytesSent { get; }

        event OnPacketEventHandler OnPacketEvent;
        bool IsOpened { get; }

        void Send( MemoryStream data );
        Task<bool> TryReconnect( int timeout );
        void Disconnect();

        event DisconnectedHandler Disconnected;
    }
}
